package com.isoft.illustrationsdraw.service.impl;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.springframework.stereotype.Service;

import com.isoft.illustrationsdraw.Constants;
import com.isoft.illustrationsdraw.exception.TokenExpiredException;
import com.isoft.illustrationsdraw.exception.TokenInvalidException;
import com.isoft.illustrationsdraw.service.AuthService;
import com.isoft.illustrationsdraw.service.EmailService;
import com.isoft.illustrationsdraw.service.JWTService;

@Service
public class AuthServiceImpl implements AuthService {
    
    private final EmailService emailService;
    private final JWTService jwtService;

    public AuthServiceImpl(EmailService emailService, JWTService jwtService) {
        this.emailService = emailService;
        this.jwtService = jwtService;
    }


    @Override
    public String generateMagicLink(String email) {
        String token = jwtService.generateLogInToken(email);
        if (token == null) {
            return null;
        }
        String magicLink = Constants.Auth.MAGIC_LINK + token;

        return magicLink;
    }

    @Override
    public boolean sendMagicLink(String toEmail, String magicLink) {
        return emailService.sendMagicLink(toEmail, magicLink);
    }

    @Override
    public String keepLoggedIn(String currentToken) {

        if (!jwtService.validateToken(currentToken)) {
            return null;
        }

        Long userId = jwtService.getUserIdFromToken(currentToken);
        if (userId == null) {
            return null;
        }
     
        String newToken = jwtService.generateLongTermToken(userId);
        if (newToken == null) {
            return null;
        }
        return newToken;
    }
    
    @Override
    public String refreshLongTermToken(String token) {
        // 获取长效令牌的过期时间
        Date expiration = jwtService.getLongTermTokenExpirationTime(token);
        
        // 获取当前时间
        Date now = new Date();
        
        // 如果过期时间为空，表示令牌无效，抛出令牌无效的异常
        if (expiration == null) {
            throw new TokenInvalidException("The token is invalid.");
        }

        // 计算令牌过期时间与当前时间的差距
        long diffInMillis = expiration.getTime() - now.getTime();
        long diffInDays = TimeUnit.MILLISECONDS.toDays(diffInMillis);
        Long userId = jwtService.getUserIdFromToken(token);
        if (userId == null) {
            throw new TokenInvalidException("The token is invalid.");
        }

        // 如果令牌有效，返回 null
        if (diffInMillis > 0) {
            return null;
        }

        // 如果已过期且过期时间不超过 5 天，生成新的长效令牌
        if (diffInDays > -5) {
            return jwtService.generateLongTermToken(userId); // 生成新的长效令牌
        }

        // 如果已过期超过 5 天，抛出异常
        throw new TokenExpiredException("The token has expired for more than 5 days.");
    }

}
